package com.easy.cloud.web.oauth.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.easy.cloud.web.component.core.enums.StatusEnum;
import com.easy.cloud.web.component.security.domain.AuthenticationUser;
import com.easy.cloud.web.oauth.service.ISecurityUserDetailsService;
import com.easy.cloud.web.service.upms.api.feign.UpmsFeignClientService;
import com.easy.cloud.web.service.upms.api.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * 账号信息数据库校验配置
 *
 * @author GR
 * @date 2021-3-26 17:07
 */
@Service
public class SecurityUserDetailsServiceImpl implements ISecurityUserDetailsService {

    @Autowired
    private PasswordEncoder bCryptPasswordEncoder;

    @Lazy
    @Autowired
    private UpmsFeignClientService upmsFeignClientService;

    /**
     * Security过滤器通过调用loadUserByUsername方法获取用户详情， WebSecurityConfigurerAdapter中指定密码的加密方式，Security自动校验
     * 校验成功，回调AuthenticationSuccessHandler，反之AuthenticationFailureHandler
     *
     * @param userName 账号
     * @return org.springframework.security.core.userdetails.UserDetails
     */
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        UserVO userVO = upmsFeignClientService.loadUserByUsername(userName).getData();
        return buildUserInfo(userVO);
    }

    @Override
    public UserDetails loadUserBySocial(String principal) {
        // 解析requestBodyStr
        JSONObject requestBody = JSONUtil.parseObj(principal);
        if (!requestBody.containsKey("type")) {
            throw new UsernameNotFoundException("当前登录类型不能为空");
        }

        // 获取用户信息
        UserVO userVO = upmsFeignClientService.loadSocialUser(requestBody).getData();
        return buildUserInfo(userVO);
    }

    /**
     * 构建用户信息
     *
     * @param userVO 用户信息
     * @return org.springframework.security.core.userdetails.UserDetails
     */
    private UserDetails buildUserInfo(UserVO userVO) {
        // 用户信息为空
        if (Objects.isNull(userVO)) {
            throw new UsernameNotFoundException("当前用户信息不存在");
        }

        // 定义用户角色
        String userChannel = null;
        // 角色为空，设置无法识别
        if (CollUtil.isNotEmpty(userVO.getRoleCodes())) {
            userChannel = RandomUtil.randomEle(CollUtil.newArrayList(userVO.getRoleCodes()));
        }

        if (StrUtil.isBlank(userVO.getUserName())) {
            userVO.setUserName(userVO.getNickName());
        }

        if (StrUtil.isBlank(userVO.getPassword())) {
            // 此处设置默认密码，是为了避免密码为空的问题
            userVO.setPassword("123456");
        }

        // Authority 即角色，随机绑定一个其中的角色信息
        return new AuthenticationUser(userVO.getId(), userVO.getUserName(), userVO.getPassword(),
                userChannel, userVO.getTenantId(), true, true, true,
                userVO.getStatus() != StatusEnum.FREEZE_STATUS,
                AuthorityUtils.createAuthorityList(userVO.getPermissions().toArray(new String[0])));
    }
}
